/*
 * TimeLine.java
 *
 * Created on September 6, 2007, 8:25 PM
 * 16, October, 2009: Class normalized along with the classes ExcludeColumns, ExcludeTables, InputAttribs, TimeLine and StockExperiments in order to allow the creation of an
 * abstract class AttributeFabric, in order to be conformant with design pattern method.
 * 06, April, 2011: Base class no longer inherits from class Table, rather table is now a composition object.
 * 18, November, 2011: Class modified to use TableFactory.
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package portfolio.dbHost.project.attributes;

import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.sql.Connection;
import java.sql.Date;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Calendar;
import java.util.Vector;
import javax.swing.JPopupMenu;
import javax.swing.JTable;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import misellanea.Miscellanea;
import misellanea.MiscellaneaDB;
import portfolio.dbHost.dataBases.dbTable.Table;
import portfolio.dbHost.dataBases.dbTable.TableFactory;
import portfolio.dbHost.project.Project;

/**
 *
 * @author ACA
 */
public class TimeLine  implements AbstractAttribute, MouseListener
{
     private Table table = null;

    static final public  String       TABLE_NAME       = "timeline";
    static final private String       COLUMN_BEGINDATE = "begindate";
    static final private String       COLUMN_ENDDATE   = "enddate";
    static final private String       COLUMN_TERM      = "term";
    static final private String       COLUMN_UNTILL    = "till";
    static final private String       TYPE_BEGINDATE   = TimeLine.COLUMN_BEGINDATE + " DATE";
    static final private String       TYPE_ENDDATE     = TimeLine.COLUMN_ENDDATE   + " DATE";
    static final private String       TYPE_TERM        = TimeLine.COLUMN_TERM      + " INT(11)";
    
    private String       sEndTerm      = null;  //0j0    
    private Vector []    vTimeLine     = null;            
    
    static final public int TIMELINE_BEGINDATE = 0;
    static final public int TIMELINE_ENDDATE   = 1;
    static final public int TIMELINE_TERM      = 2;
    static final public int TIMELINE_SIZE      = 3;
    
    
    static final public Object []  MONTHS_ARRAY_OBJECT = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", 
                                  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
    
    /**
     * @Overrides parent's method Table.mousePressed 
     */
    int mouseReleased = 1;
    public void mouseClicked(MouseEvent e) {
        String sClassName = e.getClass().getName();
        System.out.println (mouseReleased++ + " className: " + sClassName + ": TimeLine:           [[[[[[[[[[[[[[[[[[[[[[[[[ Mouse Clicked ]]]]]]]]]]]]]]]]]]]]]]]]]");
//        System.out.println ("TimeLine:           [[[[[[[[[[[[[[[[[[[[[[[[[ Mouse cliked ]]]]]]]]]]]]]]]]]]]]]]]]]");
//        throw new UnsupportedOperationException("Not supported yet.");
    }

    public void mousePressed(MouseEvent e) {
        String sClassName = e.getClass().getName();
        System.out.println (mouseReleased++ + " className: " + sClassName + ": TimeLine:           [[[[[[[[[[[[[[[[[[[[[[[[[ Mouse Pressed ]]]]]]]]]]]]]]]]]]]]]]]]]");
//        System.out.println ("TimeLine:           [[[[[[[[[[[[[[[[[[[[[[[[[ Mouse cliked ]]]]]]]]]]]]]]]]]]]]]]]]]");
//        throw new UnsupportedOperationException("Not supported yet.");
    }
    public void mouseReleased(MouseEvent e) {
        String sClassName = e.getClass().getName();
        System.out.println (mouseReleased++ + " className: " + sClassName + ": TimeLine:           [[[[[[[[[[[[[[[[[[[[[[[[[ Mouse Released ]]]]]]]]]]]]]]]]]]]]]]]]]");
//        throw new UnsupportedOperationException("Not supported yet.");
    }

    public void mouseEntered(MouseEvent e) {
        String sClassName = e.getClass().getName();
        System.out.println (mouseReleased++ + " className: " + sClassName + ": TimeLine:           [[[[[[[[[[[[[[[[[[[[[[[[[ Mouse Entered ]]]]]]]]]]]]]]]]]]]]]]]]]");
//        System.out.println ("TimeLine:           [[[[[[[[[[[[[[[[[[[[[[[[[ Mouse cliked ]]]]]]]]]]]]]]]]]]]]]]]]]");
//        throw new UnsupportedOperationException("Not supported yet.");
    }

    public void mouseExited(MouseEvent e) {
        String sClassName = e.getClass().getName();
        System.out.println (mouseReleased++ + " className: " + sClassName + ": TimeLine:           [[[[[[[[[[[[[[[[[[[[[[[[[ Mouse Exited ]]]]]]]]]]]]]]]]]]]]]]]]]");
//        System.out.println ("TimeLine:           [[[[[[[[[[[[[[[[[[[[[[[[[ Mouse cliked ]]]]]]]]]]]]]]]]]]]]]]]]]");
//        throw new UnsupportedOperationException("Not supported yet.");
    }
    /**
     * Creates a new instance of TimeLine
     */
//    public TimeLine(Project projectParam) throws Exception
//    {
//        super (projectParam, TimeLine.TABLE_NAME);
//
//        this.validate ();
//        String [] sTimeLineTmp = this.get ();
//        Integer ITerm = new Integer (sTimeLineTmp [TimeLine.TIMELINE_TERM]);
//        String sEndSelectedDate = sTimeLineTmp [TimeLine.TIMELINE_ENDDATE];
//
//        sEndTerm = this.setTerm(ITerm, sEndSelectedDate);
//    }
    /**
     * 
     */
    public TimeLine(Project projectParam) throws Exception
    {
////        super (projectParam);
////        super.setName(TimeLine.TABLE_NAME);
//        int iDBType = projectParam.getDBHost().getDBType();
//        if (iDBType == Host.DB_TYPE_MYSQL) {
//            table = new MysqlTable (projectParam);
//        } else if (iDBType == Host.DB_TYPE_ODBC) {
//            table = new OdbcTable (projectParam);
//        } else {
//            throw new Exception ("Unknown Data Base.");
//        }
        TableFactory tableFactory = new TableFactory ();
        table = tableFactory.getDBType(projectParam.getProjectDBase());
        table.setName(TimeLine.TABLE_NAME);

        table.getDBase().setTablesVector();
        Vector vTables = table.getDBase().showTables();
        if (vTables == null || !vTables.contains(TimeLine.TABLE_NAME)) {
            this.create ();
        }
    }
    /**
     * 
     * @param sBeginDate
     * @param sEndDate
     * @param ITerm
     * @throws java.lang.Exception
     */
    public void initComponents (String sBeginDate, String sEndDate, Integer ITerm) throws Exception
    {
        Vector vValues = new Vector ();
        vValues.add (sBeginDate);
        vValues.add (sEndDate);
        vValues.add (ITerm.toString());
        this.insert (vValues);
        
        String  sEndSelectedDate = (this.get ()) [TimeLine.TIMELINE_ENDDATE];

        sEndTerm = this.setTerm (ITerm, sEndSelectedDate);
    }
    /**
     *
     */
    public DefaultMutableTreeNode processHierarchy ( )
    {
        DefaultMutableTreeNode node = new DefaultMutableTreeNode (TimeLine.TABLE_NAME);
        
        DefaultMutableTreeNode nBeginDateCol = new DefaultMutableTreeNode (TimeLine.COLUMN_BEGINDATE);
        DefaultMutableTreeNode nBeginDate    = new DefaultMutableTreeNode (vTimeLine [0].get(0).toString());
        nBeginDateCol.add(nBeginDate);
        node.add(nBeginDateCol);
        
        DefaultMutableTreeNode nEndDateCol = new DefaultMutableTreeNode (TimeLine.COLUMN_ENDDATE);
        String sEndDate = vTimeLine [TimeLine.TIMELINE_ENDDATE].get(0).toString();
        DefaultMutableTreeNode nEndDate    = new DefaultMutableTreeNode (sEndDate);
        nEndDateCol.add(nEndDate);
        node.add(nEndDateCol);
        
        DefaultMutableTreeNode nTermCol = new DefaultMutableTreeNode (TimeLine.COLUMN_TERM);
        String sTerm = vTimeLine [TimeLine.TIMELINE_TERM].get(0).toString();
        DefaultMutableTreeNode nTerm    = new DefaultMutableTreeNode (sTerm);
        nTermCol.add(nTerm);        
        node.add(nTermCol);
        
        DefaultMutableTreeNode nTillCol = new DefaultMutableTreeNode (TimeLine.COLUMN_UNTILL);
//        String sTerm = vTimeLine [1].get(0).toString();
        DefaultMutableTreeNode nTill    = new DefaultMutableTreeNode (sEndTerm);
        nTillCol.add(nTill);        
        node.add(nTillCol);
        
        return node;
    }
    /**
     *
     * @param dbTreeParam 
     * @param iXPos 
     * @param iYPos 
     */
    public void getPopupOptions (JTree dbTreeParam, int iXPos, int iYPos)
    {
        JTree dbaseTree = dbTreeParam;       

        JPopupMenu treeOptionsMenu = new JPopupMenu ("Options");
        dbaseTree.add(treeOptionsMenu);
        
        dbaseTree.addMouseListener(this);

        treeOptionsMenu.setLocation (iXPos, iYPos);
        treeOptionsMenu.show (treeOptionsMenu, iXPos, iYPos);
        
        return;
    } /* end method getPopupOptions */      
    /**
     * Returns TimeLine attributes, in a String array of 3 elements, distributed as follows:
     * One row and three columns of the TimeLine Table distributed as:
     * Column 0 BEGINDATE
     * Column 1 ENDDATE
     * Column 2 TERM
     */
     public String [] get ()
     {
         if (vTimeLine == null) {
             return null;
         }
         String [] sTimeLineOut = new String [TimeLine.TIMELINE_SIZE];
         sTimeLineOut [TimeLine.TIMELINE_BEGINDATE] =  (String) vTimeLine [TimeLine.TIMELINE_BEGINDATE].get(0);
         sTimeLineOut [TimeLine.TIMELINE_ENDDATE]   =  (String) vTimeLine [TimeLine.TIMELINE_ENDDATE].get(0);
         sTimeLineOut [TimeLine.TIMELINE_TERM]      =  (String) vTimeLine [TimeLine.TIMELINE_TERM].get (0);
         
         return sTimeLineOut;
     }
    /******************************************************************
     * method merged with setStringTer,                               *
     ******************************************************************/
    private String setTerm (Integer iTermParam, String sEndSelectedDate)
    {
        if (sEndSelectedDate == null || iTermParam == null)
            return null;

        if (sEndSelectedDate.contains("'")) {
            sEndSelectedDate = sEndSelectedDate.substring(1, sEndSelectedDate.length() -1);
        }
        
        if (!sEndSelectedDate.contains("\"")) {
            sEndSelectedDate = "\"" + sEndSelectedDate + "\"";
        }
        
        String sEndSelectedTerm = null;
        Integer iTerm = iTermParam;
        int iTmp = 0;
        if (iTerm != null) {
            iTmp = iTerm.intValue ();
        }

        if (sEndSelectedDate != null) {
            Vector vTmpTimeLine = TimeLine.setTimeLine (sEndSelectedDate, iTmp);
            sEndSelectedTerm = vTmpTimeLine.lastElement().toString();
        } 
        
        return sEndSelectedTerm;
    } /* end method setTerm */
    /*
     * 
     */
    public Object getTreeObject (Object [] oPathParam)
    {
        if (oPathParam == null) {
            return null;
        }
        if (oPathParam.length <2) { //0j0 get size
            return null;
        }
        if (!oPathParam [1].toString().equals(TimeLine.TABLE_NAME)) {
           return null;  //error, no database found
        }
        
        return this;
    } /* end method getTreeObject */
    /**
     * 
     * @throws java.lang.Exception 
     * 
     */
    public void create () throws Exception
    {
        table.setName(TimeLine.TABLE_NAME);
        table.create (TimeLine.TYPE_BEGINDATE + ", " + TimeLine.TYPE_ENDDATE + ", " + TimeLine.TYPE_TERM);
    }
    /**
     * 
     * @throws java.lang.Exception 
     * 
     * 
     */
//    public void insert (Vector vValues) throws Exception
//    {
//        Vector vColumns = new Vector ();
//        vColumns.add (TimeLine.COLUMN_BEGINDATE);
//        vColumns.add (TimeLine.COLUMN_ENDDATE);
//        vColumns.add (TimeLine.COLUMN_TERM);
//        Vector vValuesTmp = new Vector ();
//        vValuesTmp.add (TimeLine.TIMELINE_BEGINDATE, "'" + vValues.get(TimeLine.TIMELINE_BEGINDATE) + "'");
//        vValuesTmp.add (TimeLine.TIMELINE_ENDDATE,   "'" + vValues.get(TimeLine.TIMELINE_ENDDATE) + "'");
//        vValuesTmp.add (TimeLine.TIMELINE_TERM,      vValues.get(TimeLine.TIMELINE_TERM));
//
//        table.insertSingleRow(vColumns, vValuesTmp);
//        table.buildColumns();
//    }
// This insert vertion was created on 13/04/12
    public void insert (Vector vValues) throws Exception
    {
        Vector vColumns = new Vector ();
        vColumns.add (TimeLine.COLUMN_BEGINDATE);
        vColumns.add (TimeLine.COLUMN_ENDDATE);
        vColumns.add (TimeLine.COLUMN_TERM);
        Vector vValuesTmp = new Vector ();
        vValuesTmp.add (TimeLine.TIMELINE_BEGINDATE, "'" + vValues.get(TimeLine.TIMELINE_BEGINDATE) + "'");
        vValuesTmp.add (TimeLine.TIMELINE_ENDDATE,   "'" + vValues.get(TimeLine.TIMELINE_ENDDATE) + "'");
        vValuesTmp.add (TimeLine.TIMELINE_TERM,      vValues.get(TimeLine.TIMELINE_TERM));

        table.insertSingleRow(vColumns, vValuesTmp);
        table.buildColumns();
        
        vTimeLine = new Vector [TimeLine.TIMELINE_SIZE];
        vTimeLine [TimeLine.TIMELINE_BEGINDATE] = new Vector ();
        vTimeLine [TimeLine.TIMELINE_ENDDATE]   = new Vector ();
        vTimeLine [TimeLine.TIMELINE_TERM]      = new Vector ();
        
        vTimeLine [TimeLine.TIMELINE_BEGINDATE].add (vValues.get(TimeLine.TIMELINE_BEGINDATE));
        vTimeLine [TimeLine.TIMELINE_BEGINDATE].add (TimeLine.COLUMN_BEGINDATE);
        
        vTimeLine [TimeLine.TIMELINE_ENDDATE].add (vValues.get(TimeLine.TIMELINE_ENDDATE));
        vTimeLine [TimeLine.TIMELINE_ENDDATE].add (TimeLine.COLUMN_ENDDATE);
        
        vTimeLine [TimeLine.TIMELINE_TERM].add (vValues.get(TimeLine.TIMELINE_TERM));
        vTimeLine [TimeLine.TIMELINE_TERM].add (TimeLine.COLUMN_TERM);
    }
    /**
     * <<<<<<<<<<<<<<< 0j0 Experiment >>>>>>>>>>>>>>>>>>>>>
     */
    static public Vector read (Connection connection, String sDBName)  throws Exception
    {    
        try {
            if (connection == null)
                throw new Exception ("null connection.");
            
            ResultSet resultSet = Table.getQuery(connection, sDBName, "*", TimeLine.TABLE_NAME);
            Object [][] OMatrix = Table.transferObjectResultSet2Matrix(resultSet, 0);
/*ACA NEW*/            if (OMatrix == null) {/**/
/*ACA NEW*///                throw new Exception ("OMatrix null.");*/
/*ACA NEW*/                return null;/**/
/*ACA NEW*/            }/**/

            String sBeginDate  =  (String)OMatrix [0][TimeLine.TIMELINE_BEGINDATE];
            String sEndDate    =  (String)OMatrix [0][TimeLine.TIMELINE_ENDDATE];
            String sTerm       =  (String)OMatrix [0][TimeLine.TIMELINE_TERM];

            Vector vOutVector = new Vector ();
            
            Date tmpDate = java.sql.Date.valueOf (sBeginDate);
            Calendar tmpBeginDate = Calendar.getInstance();
            tmpBeginDate.setTime(tmpDate);
            vOutVector.add(tmpBeginDate);
            
            tmpDate = java.sql.Date.valueOf (sEndDate);
            Calendar tmpEndDate = Calendar.getInstance();
            tmpEndDate.setTime (tmpDate);
            vOutVector.add(tmpEndDate);
            
            int iTmp = Integer.parseInt (sTerm);
            Integer tmpITerm = new Integer (iTmp);
            vOutVector.add (tmpITerm);
                    
            return vOutVector;
        } catch (Exception ex) {
            throw new Exception (ex);
        }            
    }
    /**
     * 
     */
    private static Vector setTimeLine (String sBeginDate, int iTerm)
    {
        if (iTerm <= 0)
            return null;
        if (sBeginDate == null)
            return null;
        Vector vTimeLine = new Vector ();

        sBeginDate = sBeginDate.substring(1, sBeginDate.length() -1);
        vTimeLine.add (sBeginDate);
        //System.out.println (sBeginDate);

        for (int i = 0; i < iTerm; i++) {
            String sDate = vTimeLine.lastElement ().toString ();
            String sNxtDate = Miscellanea.getNextDateRecord (sDate);
            vTimeLine.add (sNxtDate);
            //System.out.println (i + " " + sNxtDate);
        }

        //System.out.println (sNxtDate);                
        return vTimeLine;
    } /* end setTermTimeLine */

    public Table getTable() {
        return table;
    }
    /**
     * Note 1: TimeLile, must be on column 0 allways.
     * Note 2: Former methods MiscellaneaDB.GetVectorTimeLine
     */
    public static Vector getVector (JTable jTableParam, int iTermParam)
    {
        Vector vTempTimeLine = new Vector ();
        int iRow = jTableParam.getRowCount();

        for (int i = 0; i < iRow; i++) {
            vTempTimeLine.add (jTableParam.getValueAt (i, 0).toString ()); 
        }

        for (int i = 0; i < iTermParam; i++) {
            String sDate = vTempTimeLine.lastElement ().toString ();
            String sNxtDate = Miscellanea.getNextDateRecord (sDate);
            vTempTimeLine.add (sNxtDate);
        }

        //System.out.println (sNxtDate);                
        return vTempTimeLine;
    } /* end method getVectorTimeLine */
    /**
     * 
     */
    public static Vector getVector (ResultSet rs, int iTermParam) throws SQLException, Exception
    {
        if (rs == null) {
            throw new Exception ("Null resultSet.");
        }

        rs.last();                
        int iRow = rs.getRow();
        rs.first();

        if (iRow <= 0 ) {
            throw new Exception ("ResultSet contained no records" );
        }

        Vector vTempTimeLine = new Vector ();

        for (int i = 0; i < iRow; i++) {
            Vector vCurrentRow = MiscellaneaDB.getCurrentRowFromResultSet(rs, 1);
            vTempTimeLine.add (vCurrentRow.get(0).toString());
            rs.next ();
//                    System.out.println (vTempTimeLine.get(i).toString());
        }
//                System.out.println ("-------- plus term -------");

        for (int i = 0; i < iTermParam; i++) {
            String sDate = vTempTimeLine.lastElement ().toString ();
            String sNxtDate = Miscellanea.getNextDateRecord (sDate);
            vTempTimeLine.add (sNxtDate);

//                    System.out.println (vTempTimeLine.get(i + iRow).toString());
        }

        return vTempTimeLine;
    } /* end method getVectorTimeLine */
}
